package hierarchy

import (
	"errors"
	"fmt"
	"gitcode.com/G-YT/ANN/server/global"
	"gitcode.com/G-YT/ANN/server/model/common/request"
	healthReq "gitcode.com/G-YT/ANN/server/model/health/request"
	"gitcode.com/G-YT/ANN/server/model/hierarchy"
	hierarchyReq "gitcode.com/G-YT/ANN/server/model/hierarchy/request"
	"gorm.io/gorm"
	"strings"
)

type FdArticleGraphicService struct {
}

// CreateFdArticleGraphic 创建FdArticleGraphic记录
// Author [piexlmax](https://github.com/piexlmax)
func (fdArticleGraphicService *FdArticleGraphicService) CreateFdArticleGraphic(fdArticleGraphic *hierarchy.FdArticleGraphic) (err error) {
	err = global.GVA_DB.Create(fdArticleGraphic).Error
	return err
}

// DeleteFdArticleGraphic 删除FdArticleGraphic记录
// Author [piexlmax](https://github.com/piexlmax)
func (fdArticleGraphicService *FdArticleGraphicService) DeleteFdArticleGraphic(fdArticleGraphic hierarchy.FdArticleGraphic) (err error) {
	var physique healthReq.PhysiqueArticle
	var solarTerms healthReq.FdJqArticle
	var efficacy healthReq.FdEfficacyArticle
	var disease healthReq.DiseaseArticle
	// 查询是否存在关联体質
	if !errors.Is(global.GVA_DB.Where("article_id = ? AND type = 'graphic'", fdArticleGraphic.ID).Preload("Physique").Preload("FdArticleGraphic").First(&physique).Error, gorm.ErrRecordNotFound) {
		return errors.New("請先取消體質管理中【" + physique.Physique.Name + "】與【" + physique.FdArticleGraphic.Title + "】的關聯關係")
	}
	// 查询是否存在关联节气
	if !errors.Is(global.GVA_DB.Where("article_id = ? AND type = 'graphic'", fdArticleGraphic.ID).Preload("SolarTerms").Preload("FdArticleGraphic").First(&solarTerms).Error, gorm.ErrRecordNotFound) {
		return errors.New("請先取消節氣管理中【" + solarTerms.SolarTerms.JqName + "】與【" + solarTerms.FdArticleGraphic.Title + "】的關聯關係")
	}
	// 查询是否存在关联功效
	if !errors.Is(global.GVA_DB.Where("article_id = ? AND type = 'graphic'", fdArticleGraphic.ID).Preload("Efficacy").Preload("FdArticleGraphic").First(&efficacy).Error, gorm.ErrRecordNotFound) {
		return errors.New("請先取消功效管理中【" + efficacy.Efficacy.Name + "】與【" + efficacy.FdArticleGraphic.Title + "】的關聯關係")
	}
	// 查询是否存在关联病症
	if !errors.Is(global.GVA_DB.Where("article_id = ? AND type = 'graphic'", fdArticleGraphic.ID).Preload("Disease", func(db *gorm.DB) *gorm.DB {
		return db.Preload("DiseaseList")
	}).Preload("FdArticleGraphic").First(&disease).Error, gorm.ErrRecordNotFound) {
		return errors.New("請先取消病症管理中【" + disease.Disease.DiseaseList.Name + "】下的【" + disease.Disease.Name + "】與【" + disease.FdArticleGraphic.Title + "】的關聯關係")
	}
	err = global.GVA_DB.Delete(&fdArticleGraphic).Error
	return err
}

// DeleteFdArticleGraphicByIds 批量删除FdArticleGraphic记录
// Author [piexlmax](https://github.com/piexlmax)
func (fdArticleGraphicService *FdArticleGraphicService) DeleteFdArticleGraphicByIds(ids request.IdsReq) (err error) {
	var physique healthReq.PhysiqueArticle
	var solarTerms healthReq.FdJqArticle
	var efficacy healthReq.FdEfficacyArticle
	var disease healthReq.DiseaseArticle
	// 查询是否存在关联体質
	if !errors.Is(global.GVA_DB.Where("article_id in ? AND type = 'graphic'", ids.Ids).Preload("Physique").Preload("FdArticleGraphic").First(&physique).Error, gorm.ErrRecordNotFound) {
		return errors.New("請先取消體質管理中【" + physique.Physique.Name + "】與【" + physique.FdArticleGraphic.Title + "】的關聯關係")
	}
	// 查询是否存在关联节气
	if !errors.Is(global.GVA_DB.Where("article_id in ? AND type = 'graphic'", ids.Ids).Preload("SolarTerms").Preload("FdArticleGraphic").First(&solarTerms).Error, gorm.ErrRecordNotFound) {
		return errors.New("請先取消節氣管理中【" + solarTerms.SolarTerms.JqName + "】與【" + solarTerms.FdArticleGraphic.Title + "】的關聯關係")
	}
	// 查询是否存在关联功效
	if !errors.Is(global.GVA_DB.Where("article_id in ? AND type = 'graphic'", ids.Ids).Preload("Efficacy").Preload("FdArticleGraphic").First(&efficacy).Error, gorm.ErrRecordNotFound) {
		return errors.New("請先取消功效管理中【" + efficacy.Efficacy.Name + "】與【" + efficacy.FdArticleGraphic.Title + "】的關聯關係")
	}
	// 查询是否存在关联病症
	if !errors.Is(global.GVA_DB.Where("article_id in ? AND type = 'graphic'", ids.Ids).Preload("Disease", func(db *gorm.DB) *gorm.DB {
		return db.Preload("DiseaseList")
	}).Preload("FdArticleGraphic").First(&disease).Error, gorm.ErrRecordNotFound) {
		return errors.New("請先取消病症管理中【" + disease.Disease.DiseaseList.Name + "】下的【" + disease.Disease.Name + "】與【" + disease.FdArticleGraphic.Title + "】的關聯關係")
	}
	err = global.GVA_DB.Delete(&[]hierarchy.FdArticleGraphic{}, "id in ?", ids.Ids).Error
	return err
}

// UpdateFdArticleGraphic 更新FdArticleGraphic记录
// Author [piexlmax](https://github.com/piexlmax)
func (fdArticleGraphicService *FdArticleGraphicService) UpdateFdArticleGraphic(fdArticleGraphic hierarchy.FdArticleGraphic) (err error) {
	//updateFields := map[string]interface{}{
	//	"title":          fdArticleGraphic.Title,
	//	"briefly":        fdArticleGraphic.Briefly,
	//	"cover":          fdArticleGraphic.Cover,
	//	"video_link":     fdArticleGraphic.VideoLink,
	//	"details":        fdArticleGraphic.Details,
	//	"status":         fdArticleGraphic.Status,
	//	"is_vip":         fdArticleGraphic.IsVip,
	//	"level_one_id":   fdArticleGraphic.LevelOneID,
	//	"level_two_id":   fdArticleGraphic.LevelTwoID,
	//	"level_three_id": fdArticleGraphic.LevelThreeID,
	//}
	//err = global.GVA_DB.Updates(updateFields).Error
	err = global.GVA_DB.Save(&fdArticleGraphic).Error
	return err
}

// GetFdArticleGraphic 根据id获取FdArticleGraphic记录
// Author [piexlmax](https://github.com/piexlmax)
func (fdArticleGraphicService *FdArticleGraphicService) GetFdArticleGraphic(id uint, userID uint) (fdArticleGraphic hierarchy.FdArticleGraphic, err error) {
	var collect hierarchy.FdArticleCollect
	var like hierarchy.FdArticleLike
	var articleGraphic hierarchy.FdArticleGraphic
	coErr := global.GVA_DB.Where("fd_article_id = ? and user_id = ? and fd_article_type = ?", id, userID, "graphic").First(&collect)
	liErr := global.GVA_DB.Where("fd_article_id = ? and user_id = ? and fd_article_type = ?", id, userID, "graphic").First(&like)
	db := global.GVA_DB.Where("id = ?", id).First(&articleGraphic)
	err = db.Error
	if coErr.Error != nil {
		articleGraphic.IsCollect = false
	} else {
		articleGraphic.IsCollect = true
	}
	if liErr.Error != nil {
		articleGraphic.IsPraise = false
	} else {
		articleGraphic.IsPraise = true
	}
	articleGraphic.PV += 1
	db.Update("pv", articleGraphic.PV)
	// 处理点赞量和浏览量
	//praise, pv := fdArticleGraphicService.GetPraiseAndPv(articleGraphic.PV)
	fdArticleGraphic.ID = articleGraphic.ID
	fdArticleGraphic.CreatedAt = articleGraphic.CreatedAt
	fdArticleGraphic.UpdatedAt = articleGraphic.UpdatedAt
	fdArticleGraphic.DeletedAt = articleGraphic.DeletedAt
	fdArticleGraphic.LevelOneID = articleGraphic.LevelOneID
	fdArticleGraphic.LevelOne = articleGraphic.LevelOne
	fdArticleGraphic.LevelTwoID = articleGraphic.LevelTwoID
	fdArticleGraphic.LevelTwo = articleGraphic.LevelTwo
	fdArticleGraphic.LevelThreeID = articleGraphic.LevelThreeID
	fdArticleGraphic.FdArticleLike = articleGraphic.FdArticleLike
	fdArticleGraphic.FdArticleCollect = articleGraphic.FdArticleCollect
	fdArticleGraphic.Title = articleGraphic.Title
	fdArticleGraphic.Briefly = articleGraphic.Briefly
	fdArticleGraphic.Cover = articleGraphic.Cover
	fdArticleGraphic.VideoLink = articleGraphic.VideoLink
	fdArticleGraphic.Details = articleGraphic.Details
	fdArticleGraphic.Status = articleGraphic.Status
	fdArticleGraphic.IsVip = articleGraphic.IsVip
	fdArticleGraphic.PraiseNum = articleGraphic.PraiseNum
	fdArticleGraphic.CollectNum = articleGraphic.CollectNum
	fdArticleGraphic.ForwardNum = articleGraphic.ForwardNum
	fdArticleGraphic.CommentNum = articleGraphic.CommentNum
	fdArticleGraphic.SearchNumber = articleGraphic.SearchNumber
	fdArticleGraphic.PV = articleGraphic.PV
	fdArticleGraphic.IsPraise = articleGraphic.IsPraise
	fdArticleGraphic.IsCollect = articleGraphic.IsCollect
	return
}

func (fdArticleGraphicService *FdArticleGraphicService) GetPraiseAndPv(num int) (praise, pv string) {
	if num < 200 {
		// 点赞量 * 0.5 拼接“w+”
		likes := int(float64(num) * 0.5)
		praise = fmt.Sprintf("%dw+", likes)
		// 浏览量直接拼接“w+”
		pv = fmt.Sprintf("%dw+", num)
	} else {
		praise = "100w+"
		pv = fmt.Sprintf("%dw+", num)
	}
	return praise, pv
}

// GetFdArticleGraphicInfoList 分页获取FdArticleGraphic记录
// Author [piexlmax](https://github.com/piexlmax)
func (fdArticleGraphicService *FdArticleGraphicService) GetFdArticleGraphicInfoList(info hierarchyReq.FdArticleGraphicSearch) (list []hierarchy.FdArticleGraphic, total int64, err error) {
	limit := info.PageSize
	offset := info.PageSize * (info.Page - 1)
	// 创建db
	db := global.GVA_DB.Table("fd_article_graphic USE INDEX (deleted_at)").Omit("details")
	var fdArticleGraphics []hierarchy.FdArticleGraphic
	// 如果有条件搜索 下方会自动创建搜索语句
	if info.StartCreatedAt != nil && info.EndCreatedAt != nil {
		db = db.Where("created_at BETWEEN ? AND ?", info.StartCreatedAt, info.EndCreatedAt)
	}

	if info.LevelOneID != nil {
		db = db.Where("level_one_id = ?", info.LevelOneID)
	}
	if info.LevelTwoID != nil {
		db = db.Where("level_two_id = ?", info.LevelTwoID)
	}
	if info.LevelThreeID != nil {
		db = db.Where("level_three_id = ?", info.LevelThreeID)
	}
	if info.Title != "" {
		db = db.Where("title LIKE ?", "%"+info.Title+"%")
	}
	err = db.Count(&total).Error
	if err != nil {
		return
	}
	if limit != 0 {
		db = db.Limit(limit).Offset(offset)
	}
	err = db.Find(&fdArticleGraphics).Error
	return fdArticleGraphics, total, err
}

// GetArticleListByLevelTwoIDs 根据二级ID集合获取文章列表
// Author [g-qs](https://gitee.com/g-qs)
func (fdArticleGraphicService *FdArticleGraphicService) GetArticleListByLevelTwoIDs(info hierarchyReq.ArticleSearchByLevelTwoIDs) (list []hierarchy.FdArticleGraphic, total int64, err error) {
	limit := info.PageSize
	offset := info.PageSize * (info.Page - 1)
	// 创建db
	db := global.GVA_DB.Table("fd_article_graphic USE INDEX (deleted_at)").Omit("details")
	var fdArticleGraphics []hierarchy.FdArticleGraphic
	// 如果有条件搜索 下方会自动创建搜索语句
	if info.StartCreatedAt != nil && info.EndCreatedAt != nil {
		db = db.Where("created_at BETWEEN ? AND ?", info.StartCreatedAt, info.EndCreatedAt)
	}
	if info.LevelTwoID != nil && info.LevelTwoIDs != "" {
		db = db.Where("level_two_id = ?", info.LevelTwoID)
	} else {
		LevelTwoIDsStr := strings.Trim(info.LevelTwoIDs, "[]")
		LevelTwoIDsArr := strings.Split(LevelTwoIDsStr, ",")
		db = db.Where("level_two_id IN (?)", LevelTwoIDsArr)
	}
	if info.LevelThreeID != nil {
		db = db.Where("level_three_id = ?", info.LevelThreeID)
	}
	if info.Title != "" {
		db = db.Where("title LIKE ?", "%"+info.Title+"%")
	}
	err = db.Count(&total).Error
	if err != nil {
		return
	}
	if limit != 0 {
		db = db.Limit(limit).Offset(offset)
	}
	err = db.Find(&fdArticleGraphics).Error
	return fdArticleGraphics, total, err
}

func (fdArticleGraphicService *FdArticleGraphicService) FdArticleLike(userID uint, id uint) (info hierarchy.FdArticleGraphic, err error) {
	var fdArticleGraphic hierarchy.FdArticleGraphic
	tdb := global.GVA_DB.Where("id = ?", id).First(&fdArticleGraphic)
	err = global.GVA_DB.Transaction(func(tx *gorm.DB) error {
		uidb := tx.Where("user_id = ? and fd_article_id = ? and fd_article_type = ?", userID, id, "graphic").First(&hierarchy.FdArticleLike{})

		if errors.Is(uidb.Error, gorm.ErrRecordNotFound) {
			fdArticleGraphic.PraiseNum += 1
			uidb = tx.Create(&hierarchy.FdArticleLike{
				UserID:        userID,
				FdArticleID:   id,
				FdArticleType: "graphic",
			})
			fdArticleGraphic.IsPraise = true
		} else {
			fdArticleGraphic.PraiseNum -= 1
			uidb = tx.Delete(&hierarchy.FdArticleLike{}, "user_id = ? and fd_article_id = ? and fd_article_type = ?", userID, id, "graphic")
			fdArticleGraphic.IsPraise = false
		}
		return tdb.Update("praise_num", fdArticleGraphic.PraiseNum).Error
	})
	//praise, pv := fdArticleGraphicService.GetPraiseAndPv(fdArticleGraphic.PV)
	info.ID = fdArticleGraphic.ID
	info.CreatedAt = fdArticleGraphic.CreatedAt
	info.UpdatedAt = fdArticleGraphic.UpdatedAt
	info.DeletedAt = fdArticleGraphic.DeletedAt
	info.LevelOneID = fdArticleGraphic.LevelOneID
	info.LevelOne = fdArticleGraphic.LevelOne
	info.LevelTwoID = fdArticleGraphic.LevelTwoID
	info.LevelTwo = fdArticleGraphic.LevelTwo
	info.LevelThreeID = fdArticleGraphic.LevelThreeID
	info.FdArticleLike = fdArticleGraphic.FdArticleLike
	info.FdArticleCollect = fdArticleGraphic.FdArticleCollect
	info.Title = fdArticleGraphic.Title
	info.Briefly = fdArticleGraphic.Briefly
	info.Cover = fdArticleGraphic.Cover
	info.VideoLink = fdArticleGraphic.VideoLink
	info.Details = fdArticleGraphic.Details
	info.Status = fdArticleGraphic.Status
	info.IsVip = fdArticleGraphic.IsVip
	info.PraiseNum = fdArticleGraphic.PraiseNum
	info.CollectNum = fdArticleGraphic.CollectNum
	info.ForwardNum = fdArticleGraphic.ForwardNum
	info.CommentNum = fdArticleGraphic.CommentNum
	info.SearchNumber = fdArticleGraphic.SearchNumber
	info.PV = fdArticleGraphic.PV
	info.IsPraise = fdArticleGraphic.IsPraise
	info.IsCollect = fdArticleGraphic.IsCollect
	return
}

func (fdArticleGraphicService *FdArticleGraphicService) FdArticleCollect(userID uint, id uint) (info hierarchy.FdArticleGraphic, err error) {
	var fdArticleGraphic hierarchy.FdArticleGraphic
	tdb := global.GVA_DB.Where("id = ?", id).First(&fdArticleGraphic)
	err = global.GVA_DB.Transaction(func(tx *gorm.DB) error {
		uidb := tx.Where("user_id = ? and fd_article_id = ? and fd_article_type = ?", userID, id, "graphic").First(&hierarchy.FdArticleCollect{})
		if errors.Is(uidb.Error, gorm.ErrRecordNotFound) {
			fdArticleGraphic.CollectNum += 1
			uidb = tx.Create(&hierarchy.FdArticleCollect{
				UserID:        userID,
				FdArticleID:   id,
				FdArticleType: "graphic",
			})
			fdArticleGraphic.IsCollect = true
		} else {
			fdArticleGraphic.CollectNum -= 1
			uidb = tx.Delete(&hierarchy.FdArticleCollect{}, "user_id = ? and fd_article_id = ? and fd_article_type = ?", userID, id, "graphic")
			fdArticleGraphic.IsCollect = false
		}
		return tdb.Update("collect_num", fdArticleGraphic.CollectNum).Error
	})
	//praise, pv := fdArticleGraphicService.GetPraiseAndPv(fdArticleGraphic.PV)
	info.ID = fdArticleGraphic.ID
	info.CreatedAt = fdArticleGraphic.CreatedAt
	info.UpdatedAt = fdArticleGraphic.UpdatedAt
	info.DeletedAt = fdArticleGraphic.DeletedAt
	info.LevelOneID = fdArticleGraphic.LevelOneID
	info.LevelOne = fdArticleGraphic.LevelOne
	info.LevelTwoID = fdArticleGraphic.LevelTwoID
	info.LevelTwo = fdArticleGraphic.LevelTwo
	info.LevelThreeID = fdArticleGraphic.LevelThreeID
	info.FdArticleLike = fdArticleGraphic.FdArticleLike
	info.FdArticleCollect = fdArticleGraphic.FdArticleCollect
	info.Title = fdArticleGraphic.Title
	info.Briefly = fdArticleGraphic.Briefly
	info.Cover = fdArticleGraphic.Cover
	info.VideoLink = fdArticleGraphic.VideoLink
	info.Details = fdArticleGraphic.Details
	info.Status = fdArticleGraphic.Status
	info.IsVip = fdArticleGraphic.IsVip
	info.PraiseNum = fdArticleGraphic.PraiseNum
	info.CollectNum = fdArticleGraphic.CollectNum
	info.ForwardNum = fdArticleGraphic.ForwardNum
	info.CommentNum = fdArticleGraphic.CommentNum
	info.SearchNumber = fdArticleGraphic.SearchNumber
	info.PV = fdArticleGraphic.PV
	info.IsPraise = fdArticleGraphic.IsPraise
	info.IsCollect = fdArticleGraphic.IsCollect
	return
}
